package com.jokerpan.project.aspect;

import com.alibaba.fastjson.JSONArray;
import com.jokerpan.project.entity.SysLogs;
import com.jokerpan.project.entity.Users;
import com.jokerpan.project.service.SysLogsService;
import com.jokerpan.project.util.ContextHolderUtils;
import com.jokerpan.project.util.IpUtil;
import com.jokerpan.project.util.UserTool;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;

@Aspect
@Component
public class LogActionAspect {
    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Resource
    SysLogsService sysLogsService;
    @Resource
    UserTool userTool;

	@Pointcut("@annotation(com.jokerpan.project.annotation.LogAction)")
	public void logPointCut() {

	}

	@Around("logPointCut()")
	public Object around(ProceedingJoinPoint point) throws Throwable {
		long beginTime = System.currentTimeMillis();
		//执行方法
		Object result = point.proceed();
		//执行时长(毫秒)
		long time = System.currentTimeMillis() - beginTime;
		//保存日志
		saveLogAction(point, time);
		return result;
	}
	//切面 配置通知
	private void saveLogAction(ProceedingJoinPoint joinPoint, long time) {
		try {
			Users users = userTool.getCurrentUser();
			if (users == null) {
				return;
			}
			MethodSignature signature = (MethodSignature) joinPoint.getSignature();
			Method method = signature.getMethod();
            SysLogs sysLogs = new SysLogs();
			com.jokerpan.project.annotation.LogAction log = method.getAnnotation(com.jokerpan.project.annotation.LogAction.class);
			if (log != null) {
				sysLogs.setUserId(users.getId());
				//注解上的描述
				String[] list = log.value().split(",");
                sysLogs.setLargeModel(list[0]); //大模块
                sysLogs.setSmallModel(list[1]);//小模块
                sysLogs.setRemark(list[2]);    //备注
                sysLogs.setActionType(list[3]);//操作类型
				SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				sysLogs.setActionDate(format.format(new Date()));
			}
            //请求的参数
            Object[] args = joinPoint.getArgs();
            Object[] str = new Object[args.length];
            for (int i = 0; i < args.length; i++) {
                if (args[i] != null && (args[i].getClass().toString().indexOf("Response") >= 0 || args[i].getClass() == MultipartFile.class)) { //过滤掉HttpServletRequest和文件类型的参数
                    continue;
                } else {
                    str[i] = args[i];
                }
            }
			//获取request
			HttpServletRequest request = ContextHolderUtils.getRequest();
			String url = request.getServletPath();
			sysLogs.setRequestUrl(url);
			//设置IP地址
			String ip = IpUtil.getRealIP(request);
			String address = ip + "（"+IpUtil.GetAddressByIp(ip)+"）";
			sysLogs.setIp(address);
            //将参数所在的数组转换成json
            String params = JSONArray.toJSONString(str);
            sysLogs.setParams(params);
            sysLogsService.add(sysLogs);
		}catch (Exception ex){ //出错处理，以免影响运行
			log.error("saveLog Exception:"+ex.getMessage());
		}finally {
			log.info("日志操作执行完毕! 耗时："+ time + "毫秒");
		}
	}

}
